/**
 * @file DriverManager.cpp
 * @brief 设备驱动管理器实现 - 现代C++/Qt风格重构版本
 * @details 负责COM端口设备的枚举、配置、状态管理和友好名称更新
 * @author 重构版本
 */

#include "DriverManager.h"
#include "C0C_Def.h"
#include "DriverStruct.h"
#include "ComDb.h"
#include "PortNum.h"
#include "Params.h"
#include "EnumDevices.h"
#include "InfFile.h"
#include "ServiceManager.h"
#include "Utils.h"
#include "ui/mainWindow.h"

#include <QDebug>
#include <QApplication>
#include <QMessageBox>
#include <QString>
#include <QByteArray>
#include <QTimer>
#include <QThread>
#include <memory>
#include <functional>
#include <RegStr.h>
#include <cfgmgr32.h>


bool DriverManager::s_comDbInitialized = false;

/**
 * @brief DriverManager构造函数
 * @param parent 父对象指针
 */
DriverManager::DriverManager(QObject *parent)
    : QObject(parent)
    , m_timer(std::make_unique<QTimer>(this))
    , m_isInitialized(false)
    , m_deviceCount(0)
{
    // 连接定时器信号
    connect(m_timer.get(), &QTimer::timeout, this, &DriverManager::onTimerTimeout);
    // 设备变动处理
    connect(this, &DriverManager::deviceChanged, this, [&] {
        // 等待安装完毕再刷新事件
        if (waitForInstallEvents(10)) {
            refreshDeviceList();
        }
        // QTimer::singleShot(500, this, [&] { });
    });
}

/**
 * @brief DriverManager析构函数
 */
DriverManager::~DriverManager()
{
    cleanup();
}

/**
 * @brief 初始化驱动管理器
 * @return 初始化是否成功
 */
bool DriverManager::initialize()
{
    if (m_isInitialized) {
        return true;
    }
    
    // 初始化COM端口数据库
    if (synchronizeComDatabase() != OperationResult::Success) {
        qDebug() << "Error: Sync ComDB Failed";
        return false;
    }
    s_comDbInitialized = true;

    // Inf文件自检
    if (selfCheckInfFileList() != OperationResult::Success) {
        qDebug() << "Error: Inf File Configuration Check Failed";
        return false;
    }

    int retry = 3;
    while (retry) {
        if (isServiceClassInstalled()) {
            break;
        }
        if (Utils::askYesNoDialog("Error", "Driver Class Is Not Install!"))
            PreInstallService();
        else
            return false;
        retry--;
    }

    m_isInitialized = true;
    // 先刷新一次
    refreshDeviceList(true);
    // 启动定时器进行定期设备扫描
    // m_timer->start(5000); // 每5秒扫描一次
    return true;
}

/**
 * @brief 清理资源
 */
void DriverManager::cleanup()
{
    if (m_timer && m_timer->isActive()) {
        m_timer->stop();
    }
    
    m_deviceInfoList.clear();
    m_isInitialized = false;
}

bool DriverManager::createPortPair()
{
    if (!m_isInitialized) {
        return false;
    }

    ADD_LOG(">>> Create Virtual Port Pair <<<");

    InfFile infFile(C0C_INF_NAME, C0C_SYS_DIR);
    const char *path = infFile.Path();
    if (!path) {
        return false;
    }

    if (InstallDriver(path)) {
        ADD_LOG(">>> SUCCESS Create Virtual Port Pair <<<");
        emit deviceChanged();
        return true;
    } else {
        ADD_LOG(">>> FAILED Create Virtual Port Pair <<<");
        return false;
    }
}

bool DriverManager::removePortPair(int num)
{
    if (!m_isInitialized) {
        return false;
    }

    ADD_LOG(QString(">>> Remove Virtual Port Pair %1 <<<").arg(num));

    if (num < 0) {
        return false;
    }

    if (UninstallDriver(num)) {
        ADD_LOG(">>> SUCCESS Remove Virtual Port Pair <<<");
        emit deviceChanged();
        return true;
    } else {
        ADD_LOG(">>> FAILED Remove Virtual Port Pair <<<");
        return false;
    }
}

/**
 * @brief 刷新设备列表
 */
void DriverManager::refreshDeviceList(bool init)
{
    if (!m_isInitialized) {
        return;
    }
    // 防止刷新重入：若正在刷新则直接返回
    if (m_isRefreshing) {
        qDebug() << "Skip refresh: already in progress";
        return;
    }
    m_isRefreshing = true;

    // qDebug() << ">>> Start Discover Drivers <<<";

    // 操作需重启系统
    bool rebootRequired = false;

    // 重新枚举设备并更新列表
    QList<DeviceInfo> oldList = m_deviceInfoList;
    m_deviceInfoList.clear();

    DeviceProperties deviceProps;
    deviceProps.setDeviceId(C0C_BUS_DEVICE_ID);

    enumerateDevices([](const QString& hardwareId) {
        // 只检测总线设备,再从总线探测端口
        return hardwareId.contains(C0C_BUS_DEVICE_ID, Qt::CaseInsensitive);
    }, deviceProps, &rebootRequired);
    ADD_LOG(QString(">>> Device found %1 <<<").arg(m_deviceCount));

    if (rebootRequired) {
        PromptReboot();
    }

    if (init) {
        // 提示初始化构建设备树
        emit initializationCompleted();
    } else {
        // 维护设备树，比较新旧列表，发出相应信号
        compareAndEmitChanges(oldList, m_deviceInfoList);
    }
    // 刷新完成，复位标记
    m_isRefreshing = false;
}

/**
 * @brief 比较两个设备是否为同一设备
 * @param device1 第一个设备
 * @param device2 第二个设备
 * @return 如果是同一设备返回true，否则返回false
 */
bool DriverManager::isSameDevice(const DeviceInfo& device1, const DeviceInfo& device2) const
{
    // 设备类型必须相同
    if (device1.type != device2.type) {
        return false;
    }

    switch (device1.type) {
    case DeviceType::BusDevice:
        // 对于总线设备，使用portPair
        return device1.portPair == device2.portPair;
    case DeviceType::VirtualPort:
    case DeviceType::VirtualPortCst:
        // 对于端口设备，使用 portName 和 portPair 进行比较
        // portName 是端口设备的主要标识符
        // portPair 用于区分同一对中的不同端口
        return device1.portName == device2.portName &&
               device1.portPair == device2.portPair;

    case DeviceType::Unknown:
    default:
        // 对于未知类型设备，使用 hardwareId 进行比较
        return device1.hardwareId == device2.hardwareId;
    }
}

/**
 * @brief 比较设备列表变化并发出信号
 * @param oldList 旧设备列表
 * @param newList 新设备列表
 */
void DriverManager::compareAndEmitChanges(const QList<DeviceInfo>& oldList,
                                          const QList<DeviceInfo>& newList)
{
    // 检查新增设备
    for (const DeviceInfo& newDevice : newList) {
        bool found = false;
        for (const DeviceInfo& oldDevice : oldList) {
            if (isSameDevice(newDevice, oldDevice)) {
                found = true;
                // 检查状态变化
                if (newDevice.state != oldDevice.state) {
                    emit deviceStateChanged(newDevice, newDevice.state);
                }
                break;
            }
        }

        if (!found) {
            emit deviceFound(newDevice);
        }
    }

    // 检查移除的设备
    for (const DeviceInfo& oldDevice : oldList) {
        bool found = false;
        for (const DeviceInfo& newDevice : newList) {
            if (isSameDevice(oldDevice, newDevice)) {
                found = true;
                break;
            }
        }

        if (!found) {
            emit deviceRemoved(oldDevice);
        }
    }
}

/**
 * @brief 枚举所有设备
 * @param filter 设备过滤器函数
 * @param deviceProps 设备属性
 * @return 找到的设备数量
 */
void DriverManager::enumerateDevices(DeviceEnumCallback filter, const DeviceProperties& deviceProps, bool *rebootRequired)
{
    m_deviceCount = 0;

    HDEVINFO hDevInfo = SetupDiGetClassDevs(
        nullptr,
        nullptr,
        nullptr,
        DIGCF_ALLCLASSES | DIGCF_PRESENT
        );
    
    if (hDevInfo == INVALID_HANDLE_VALUE) {
        qDebug() << "获取设备信息集失败";
        return;
    }
    
    SP_DEVINFO_DATA devInfoData;
    devInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
    
    // 遍历所有总线设备
    for (DWORD i = 0; SetupDiEnumDeviceInfo(hDevInfo, i, &devInfoData); i++) {
        QString hardwareId = getDeviceHardwareId(hDevInfo, &devInfoData);
        if (!hardwareId.isEmpty() && filter(hardwareId)) {
            createBusDeviceInfo(hDevInfo, &devInfoData, deviceProps, rebootRequired);
        }
    }
    
    SetupDiDestroyDeviceInfoList(hDevInfo);
}

/**
 * @brief 创建总线设备信息结构
 * @param hDevInfo 设备信息句柄
 * @param pDevInfoData 设备信息数据指针
 * @param deviceProps 设备属性
 * @return 设备信息结构
 */
bool DriverManager::createBusDeviceInfo(HDEVINFO hDevInfo, PSP_DEVINFO_DATA pDevInfoData,
                                        const DeviceProperties& deviceProps, bool *rebootRequired)
{
    DeviceInfo info;
    QStringList hwIdList = getDeviceHardwareIds(hDevInfo, pDevInfoData);
    info.hardwareId = hwIdList.last();

    // 为总线设备
    if (info.hardwareId.contains(C0C_BUS_DEVICE_ID, Qt::CaseInsensitive)) {
        // 获取Bus管理的端口号
        int portNum = PortNum::GetPortNum(hDevInfo, pDevInfoData);
        if (portNum < 0) {
            qDebug() << "WARNING:" << "BUS MANAGER PORT NUM IS INVALID!";
            return false;
        }
        // 获取其他信息
        info.portPair = generatePortPairId(portNum);
        /// FIX 驱动在已有Bus设备时创建新Bus设备将会将旧Bus设备FriendlyName清空
        auto fName = getDeviceFriendlyName(hDevInfo, pDevInfoData);
        info.friendlyName = fName.isEmpty() ? "NULL" : fName;
        info.state = getDeviceState(hDevInfo, pDevInfoData);
        /// Bus设备无端口名
        info.portName = "NULL";
        info.type = DeviceType::BusDevice;
        info.isValid = !info.hardwareId.isEmpty();
        // info.print();
        if (info.isValid) {
            m_deviceInfoList.append(info);
            m_deviceCount++;
            // 不在此处发出deviceFound信号，在新旧比较时再发出
        }
        // 获取子端口设备信息
        createPortDeviceInfo(portNum, rebootRequired);
        return true;
    }
    return false;
}

// 回调函数 - 用于加载真实端口名
static bool LoadRealPortName(
    HDEVINFO hDevInfo,
    PSP_DEVINFO_DATA pDevInfoData,
    const DeviceProperties* pDevProperties,
    bool * /*rebootRequired*/,
    void *pParam)
{
    if (pDevProperties->getDeviceId().contains(C0C_PORT_DEVICE_ID, Qt::CaseInsensitive)) {
        HKEY hKey = SetupDiOpenDevRegKey(hDevInfo, pDevInfoData, DICS_FLAG_GLOBAL, 0, DIREG_DEV, KEY_READ);
        if (hKey != INVALID_HANDLE_VALUE) {
            char portNameOld[20];
            DWORD len = sizeof(portNameOld);
            LONG err = RegQueryValueEx(hKey, "PortName", NULL, NULL, (PBYTE)portNameOld, &len);
            if (err == ERROR_SUCCESS)
                ((PortParameters *)pParam)->initRealPortName(portNameOld);
            RegCloseKey(hKey);
        }
        return TRUE;
    }
    // we never should be here
    return FALSE;
}

bool DriverManager::createPortDeviceInfo(int portNum, bool *rebootRequired)
{
    // 从Bus管理端口对号生成两个端口的名称
    QStringList portPairNameList = getBusPortPairName(portNum);
    for (int i = 0; i < portPairNameList.size(); ++i) {
        DeviceInfo info;

        auto pName = portPairNameList.at(i);
        // 从端点名称构造PortParameters并load()，从注册表中读取旧端口名PortName
        PortParameters pParams(C0C_SERVICE, pName);
        if (!pParams.load()) {
            qDebug() << "portParameters.Load Failed:" << pParams.getParametersString();
            continue;
        }

        // 构建设备属性管理对象
        DeviceProperties devProps;
        QString phDevName = QString::asprintf("%s%d", i == 0 ? C0C_PREF_DEVICE_NAME_A : C0C_PREF_DEVICE_NAME_B, portNum);
        devProps.setDeviceId(C0C_PORT_DEVICE_ID);
        devProps.setPhysicalObjectName(phDevName);

        // 从旧端口名判断是否为COM端口设备
        QString portNameOld = pParams.getPortName();
        bool isComClass = isComPortDeviceFromPortName(portNameOld);
        if (isComClass) {
            // 遍历所有设备并筛选指定的设备获取其真实名称
            EnumDevices([](const QString& hardwareId) {
                return hardwareId.contains(C0C_PORT_DEVICE_ID, Qt::CaseInsensitive) ||
                       hardwareId.contains(C0C_PORT_HW_ID_COMCLASS, Qt::CaseInsensitive) ||
                       hardwareId.contains(C0C_PORT_HW_ID_CNCCLASS, Qt::CaseInsensitive);
            }, &devProps, rebootRequired, LoadRealPortName, &pParams);
        }

        // qDebug() << "\t" << pName << pParams.getParametersString();

        // 获取端口名称（如果是COM端口设备）
        if (isComClass) {
            info.portName = pParams.getRealPortName();
        } else {
            info.portName = pName;
        }
        // 获取其他配置
        const QStringList allIds = getDeviceHardwareIdsFromPortName(pName);
        const bool hasHwIds = !allIds.isEmpty();
        info.hardwareId = hasHwIds ? allIds.last() : QString();
        const QString idsJoined = hasHwIds ? allIds.join("|") : QString();
        // 根据全部硬件ID和友好名称判断设备类型（虚拟端口可能有多个HWID）
        info.type = determineDeviceType(idsJoined, info.friendlyName, info.portName);
        info.friendlyName = getDeviceFriendlyNameFromPortName(pName);
        info.portPair = generatePortPairId(portNum);
        info.state = getDeviceStateFromPortName(pName);
        info.isValid = hasHwIds;
        // info.print();
        if (info.isValid) {
            m_deviceInfoList.append(info);
            m_deviceCount++;
            // 不在此处发出deviceFound信号，在新旧比较时再发出
        }
    }

    return true;
}

/**
 * @brief 获取设备硬件ID
 * @param hDevInfo 设备信息句柄
 * @param pDevInfoData 设备信息数据指针
 * @return 硬件ID字符串
 */
QString DriverManager::getDeviceHardwareId(HDEVINFO hDevInfo, PSP_DEVINFO_DATA pDevInfoData)
{
    DWORD requiredSize = 0;
    
    // 获取所需缓冲区大小
    SetupDiGetDeviceRegistryProperty(
        hDevInfo, pDevInfoData, SPDRP_HARDWAREID,
        nullptr, nullptr, 0, &requiredSize
        );
    
    if (requiredSize == 0) {
        return QString();
    }
    
    // 分配缓冲区并获取硬件ID
    std::vector<char> buffer(requiredSize);
    if (SetupDiGetDeviceRegistryProperty(
            hDevInfo, pDevInfoData, SPDRP_HARDWAREID,
            nullptr, reinterpret_cast<PBYTE>(buffer.data()),
            requiredSize, nullptr)) {
        
        // SPDRP_HARDWAREID 为 REG_MULTI_SZ，首个为主ID
        return QString::fromLocal8Bit(buffer.data());
    }
    
    return QString();
}

QStringList DriverManager::getDeviceHardwareIds(HDEVINFO hDevInfo, PSP_DEVINFO_DATA pDevInfoData)
{
    QStringList ids;
    DWORD requiredSize = 0;

    SetupDiGetDeviceRegistryProperty(
        hDevInfo, pDevInfoData, SPDRP_HARDWAREID,
        nullptr, nullptr, 0, &requiredSize
        );

    if (requiredSize == 0) {
        return ids;
    }

    std::vector<char> buffer(requiredSize);
    if (SetupDiGetDeviceRegistryProperty(
            hDevInfo, pDevInfoData, SPDRP_HARDWAREID,
            nullptr, reinterpret_cast<PBYTE>(buffer.data()),
            requiredSize, nullptr)) {
        // 解析 REG_MULTI_SZ: 多个以 '\0' 分隔，以双 '\0' 结束
        const char* p = buffer.data();
        const char* end = buffer.data() + requiredSize;
        while (p < end && *p != '\0') {
            QString id = QString::fromLocal8Bit(p);
            if (!id.isEmpty()) ids.push_back(id);
            p += std::strlen(p) + 1;
        }
    }
    return ids;
}

QStringList DriverManager::getDeviceHardwareIdsFromPortName(const QString &portName)
{
    // 拼完整注册表子路径
    // Exam: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\com0com\port\CNCA0
    QString instancePath = QString::asprintf(REGSTR_PATH_SYSTEMENUM "\\%s\\port\\%s", C0C_SERVICE, portName.toLocal8Bit().constData());

    HKEY hKey = NULL;
    LONG err = RegOpenKeyExA(HKEY_LOCAL_MACHINE, instancePath.toLocal8Bit().constData(), 0, KEY_READ, &hKey);
    if (err != ERROR_SUCCESS) {
        qDebug() << "RegOpenKeyEx('" << instancePath << "') failed:" << Utils::formatWinError(err);
        return {};
    }

    DWORD type = 0;
    DWORD size = 0;
    err = RegQueryValueExA(hKey, "HardwareID", NULL, &type, NULL, &size);
    if (err != ERROR_SUCCESS) {
        qDebug() << "RegQueryValueEx('HardwareID') size failed:" << Utils::formatWinError(err);
        RegCloseKey(hKey);
        return {};
    }
    if (type != REG_MULTI_SZ || size < sizeof(char)*2) {
        qDebug() << "HardwareID type unexpected (type=" << type << ")";
        RegCloseKey(hKey);
        return {};
    }

    std::vector<char> buf(size, 0);
    err = RegQueryValueExA(hKey, "HardwareID", NULL, &type, reinterpret_cast<LPBYTE>(buf.data()), &size);
    RegCloseKey(hKey);
    if (err != ERROR_SUCCESS) {
        qDebug() << "RegQueryValueEx('HardwareID') failed:" << Utils::formatWinError(err);
        return {};
    }

    QStringList hwids;
    // 解析 REG_MULTI_SZ（以双零结束）
    const char* p = buf.data();
    while (*p) {
        QString s(p);
        hwids.push_back(s);
        p += s.size() + 1;
    }
    return hwids;
}

const QStringList DriverManager::getBusPortPairName(int portNum)
{
    if (portNum < 0) {
        return QStringList();
    }
    
    // 根据com0com的命名规则生成端口对名称
    QString portA = QString("%1%2").arg(C0C_PREF_PORT_NAME_A).arg(portNum);
    QString portB = QString("%1%2").arg(C0C_PREF_PORT_NAME_B).arg(portNum);
    
    return {portA, portB};
}

QString DriverManager::generatePortPairId(int portNum)
{
    if (portNum < 0) {
        return QString();
    }
    
    // 生成端口对标识：com0com_pair_{portNum}
    return QString("pair_%1").arg(portNum);
}

/**
 * @brief 获取设备友好名称
 * @param hDevInfo 设备信息句柄
 * @param pDevInfoData 设备信息数据指针
 * @return 友好名称字符串
 */
QString DriverManager::getDeviceFriendlyName(HDEVINFO hDevInfo, PSP_DEVINFO_DATA pDevInfoData)
{
    DWORD requiredSize = 0;
    
    SetupDiGetDeviceRegistryProperty(
        hDevInfo, pDevInfoData, SPDRP_FRIENDLYNAME,
        nullptr, nullptr, 0, &requiredSize
        );
    
    if (requiredSize == 0) {
        return QString();
    }
    
    std::vector<char> buffer(requiredSize);
    if (SetupDiGetDeviceRegistryProperty(
            hDevInfo, pDevInfoData, SPDRP_FRIENDLYNAME,
            nullptr, reinterpret_cast<PBYTE>(buffer.data()),
            requiredSize, nullptr)) {
        
        return QString::fromLocal8Bit(buffer.data());
    }
    
    return QString();
}

QString DriverManager::getDeviceFriendlyNameFromPortName(const QString &portName)
{
    // 拼完整注册表子路径
    // Exam: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\com0com\port\CNCA0
    QString instancePath = QString::asprintf(REGSTR_PATH_SYSTEMENUM "\\%s\\port\\%s", C0C_SERVICE, portName.toLocal8Bit().constData());

    HKEY hKey = NULL;
    LONG err = RegOpenKeyExA(HKEY_LOCAL_MACHINE, instancePath.toLocal8Bit().constData(), 0, KEY_READ, &hKey);
    if (err != ERROR_SUCCESS) {
        qDebug() << "RegOpenKeyEx('" << instancePath << "') failed:" << Utils::formatWinError(err);
        return {};
    }

    DWORD type = 0;
    DWORD size = 0;
    err = RegQueryValueExA(hKey, "FriendlyName", NULL, &type, NULL, &size);
    if (err == ERROR_FILE_NOT_FOUND) {
        // 存在FriendlyName为空的情况
        RegCloseKey(hKey);
        return "NULL";
    } else if (err != ERROR_SUCCESS) {
        qDebug() << "RegQueryValueEx('FriendlyName') size failed:" << Utils::formatWinError(err);
        RegCloseKey(hKey);
        return "UNKNOWN";
    }
    if (type != REG_SZ || size < sizeof(char)*7) {
        qDebug() << "FriendlyName type unexpected (type=" << type << ")";
        RegCloseKey(hKey);
        return "UNKNOWN";
    }

    std::vector<char> buf(size, 0);
    err = RegQueryValueExA(hKey, "FriendlyName", NULL, &type, reinterpret_cast<LPBYTE>(buf.data()), &size);
    RegCloseKey(hKey);
    if (err != ERROR_SUCCESS) {
        qDebug() << "RegQueryValueEx('FriendlyName') failed:" << Utils::formatWinError(err);
        return "UNKNOWN";
    }

    return buf.data();
}

/**
 * @brief 获取设备状态
 * @param hDevInfo 设备信息句柄
 * @param pDevInfoData 设备信息数据指针
 * @return 设备状态枚举值
 */
DeviceState DriverManager::getDeviceState(HDEVINFO hDevInfo, PSP_DEVINFO_DATA pDevInfoData)
{
    ULONG status = 0;
    ULONG problemNumber = 0;
    
    CONFIGRET cr = CM_Get_DevNode_Status(&status, &problemNumber, pDevInfoData->DevInst, 0);
    
    if (cr != CR_SUCCESS) {
        return DeviceState::Unknown;
    }
    
    if (status & DN_HAS_PROBLEM) {
        return DeviceState::Disabled;
    }
    
    if (status & DN_STARTED) {
        return DeviceState::Active;
    }
    
    return DeviceState::Inactive;
}

DeviceState DriverManager::getDeviceStateFromPortName(const QString &portName)
{
    DEVINST devInst = 0;
    CONFIGRET crLocate = CM_Locate_DevNodeW(&devInst, const_cast<wchar_t*>(QString("com0com\\port\\" + portName).toStdWString().c_str()), CM_LOCATE_DEVNODE_NORMAL);
    if (crLocate != CR_SUCCESS) {
        // 找到映射但定位失败
        qDebug() << "Error: CM_Locate_DevNodeW failed:" << Utils::formatCfgMgrError(crLocate);
        return DeviceState::Unknown;
    }

    ULONG status = 0, prob = 0;
    CONFIGRET cr = CM_Get_DevNode_Status(&status, &prob, devInst, 0);

    if (cr != CR_SUCCESS) {
        return DeviceState::Unknown;
    }

    if (status & DN_HAS_PROBLEM) {
        return DeviceState::Disabled;
    }

    if (status & DN_STARTED) {
        return DeviceState::Active;
    }

    return DeviceState::Inactive;
}

/**
 * @brief 获取设备端口名称
 * @param hDevInfo 设备信息句柄
 * @param pDevInfoData 设备信息数据指针
 * @return 端口名称字符串
 */
QString DriverManager::getDevicePortName(HDEVINFO hDevInfo, PSP_DEVINFO_DATA pDevInfoData)
{
    HKEY hKey = SetupDiOpenDevRegKey(
        hDevInfo, pDevInfoData, DICS_FLAG_GLOBAL, 0, DIREG_DEV, KEY_READ
        );
    
    if (hKey == INVALID_HANDLE_VALUE) {
        return QString();
    }
    
    char portName[256];
    DWORD size = sizeof(portName);
    DWORD type;
    
    LONG result = RegQueryValueEx(
        hKey, "PortName", nullptr, &type, 
        reinterpret_cast<LPBYTE>(portName), &size
        );
    
    RegCloseKey(hKey);
    
    if (result == ERROR_SUCCESS && type == REG_SZ) {
        return QString::fromLocal8Bit(portName);
    }
    
    return QString();
}

/**
 * @brief 根据HwId检查设备是否为COM端口设备
 * @param hardwareId 硬件ID
 * @return 是否为COM端口设备
 */
bool DriverManager::isComPortDeviceFromHwId(const QString& hardwareId)
{
    return hardwareId.contains("COM", Qt::CaseInsensitive) ||
           hardwareId.contains("SERIAL", Qt::CaseInsensitive) ||
           hardwareId.contains("UART", Qt::CaseInsensitive);
}

/**
 * @brief 根据PortName检查设备是否为COM端口设备
 * @param portName 端口名
 * @return 是否为COM端口设备
 */
bool DriverManager::isComPortDeviceFromPortName(const QString &portName)
{
    return portName.contains(C0C_PORT_NAME_COMCLASS, Qt::CaseInsensitive);
}

/**
 * @brief 同步COM端口数据库
 * @return 操作结果
 */
OperationResult DriverManager::synchronizeComDatabase()
{
    if (s_comDbInitialized) {
        return OperationResult::Success;
    }
    
    try {
        // 使用ComDb函数进行同步操作
        ComDbSync(nullptr);
        emit comDatabaseSynchronized();
        return OperationResult::Success;
    }
    catch (...) {
        qDebug() << "Warning: ComDB Synchronize Failed";
        return OperationResult::Failed;
    }
}

OperationResult DriverManager::selfCheckInfFileList()
{
    for (const InfFileInstall *pInfFileInstall = infFileInstallList;
         pInfFileInstall->pInfName != nullptr;
         pInfFileInstall++) {
        InfFile infFile(pInfFileInstall->pInfName, C0C_SYS_DIR);
        // 确认已有Inf文件有效
        if (!infFile.Test(pInfFileInstall->pRequiredFields)) {
            return OperationResult::Failed;
        }
    }
    return OperationResult::Success;
}

bool DriverManager::isServiceClassInstalled()
{
    bool res = true;

    InfFile infFile(C0C_INF_NAME, C0C_SYS_DIR);
    const char* guidStr = infFile.ClassGUID();

    size_t guidWStrLen;
    mbstowcs_s(&guidWStrLen, nullptr, 0, guidStr, 0);
    wchar_t *guidWStr = (wchar_t*)malloc((guidWStrLen + 1) * sizeof(wchar_t));
    if (guidWStr == nullptr) {
        qDebug() << "Malloc WChar Mem Failed";
        res = false;
    }
    mbstowcs_s(&guidWStrLen, guidWStr, guidWStrLen + 1, guidStr, _TRUNCATE);

    GUID guid;
    HRESULT hr = CLSIDFromString(guidWStr, &guid);
    if (FAILED(hr)) {
        qDebug() << "Format GUID Struct Failed";
        res = false;
    }

    WCHAR className[16];
    if (!SetupDiClassNameFromGuidW(&guid, className, 16, nullptr)) {
        qDebug() << "SetupDiClassNameFromGuidW() failed:" << Utils::formatWinError(GetLastError());
        res = false;
    }

    // qDebug() << "Get Class Name" << QString::fromWCharArray(className);

    if (guidWStr)
        free(guidWStr);
    return res;
}

/**
 * @brief 更新端口信息到数据库
 * @param portName 端口名称
 * @param friendlyName 友好名称
 */
void DriverManager::updatePortInDatabase(const QString& portName, const QString& friendlyName)
{
    // 这里实现具体的数据库更新逻辑
    qDebug() << QString("更新端口 %1 的友好名称为: %2").arg(portName, friendlyName);
}

/**
 * @brief 启用设备
 * @param deviceInfo 设备信息
 * @return 操作结果
 */
OperationResult DriverManager::enableDevice(const DeviceInfo& deviceInfo)
{
    return changeDeviceState(deviceInfo, true);
}

/**
 * @brief 禁用设备
 * @param deviceInfo 设备信息
 * @return 操作结果
 */
OperationResult DriverManager::disableDevice(const DeviceInfo& deviceInfo)
{
    return changeDeviceState(deviceInfo, false);
}

/**
 * @brief 移除设备
 * @param deviceInfo 设备信息
 * @return 操作结果
 */
OperationResult DriverManager::removeDevice(const DeviceInfo& deviceInfo)
{
    // 实现设备移除逻辑
    qDebug() << QString("移除设备: %1").arg(deviceInfo.friendlyName);
    
    // 这里需要调用Windows API来移除设备
    // 具体实现取决于设备类型和系统要求
    
    emit deviceRemoved(deviceInfo);
    return OperationResult::Success;
}

/**
 * @brief 重启设备
 * @param deviceInfo 设备信息
 * @return 操作结果
 */
OperationResult DriverManager::restartDevice(const DeviceInfo& deviceInfo)
{
    // 先禁用再启用设备
    if (disableDevice(deviceInfo) == OperationResult::Success) {
        QThread::msleep(1000); // 等待1秒
        return enableDevice(deviceInfo);
    }
    
    return OperationResult::Failed;
}

/**
 * @brief 更改设备状态
 * @param deviceInfo 设备信息
 * @param enable 是否启用
 * @return 操作结果
 */
OperationResult DriverManager::changeDeviceState(const DeviceInfo& deviceInfo, bool enable)
{
    qDebug() << QString("%1设备: %2").arg(enable ? "启用" : "禁用", deviceInfo.friendlyName);
    
    // 这里需要实现具体的设备状态更改逻辑
    // 使用Windows Setup API来更改设备状态
    
    emit deviceStateChanged(deviceInfo, enable ? DeviceState::Active : DeviceState::Disabled);
    return OperationResult::Success;
}

/**
 * @brief 判断设备类型
 * @param hardwareId 硬件ID
 * @param friendlyName 友好名称
 * @param portName 端口名称
 * @return 设备类型
 */
DeviceType DriverManager::determineDeviceType(const QString& hardwareId, const QString& friendlyName, const QString& portName)
{
    // 使用C0C_Def.h中定义的宏进行设备类型判断
    
    // 总线设备：使用C0C_BUS_DEVICE_ID宏
    if (hardwareId.contains(C0C_BUS_DEVICE_ID, Qt::CaseInsensitive)) {
        return DeviceType::BusDevice;
    }
    
    // 端口设备：使用C0C_PORT_DEVICE_ID宏
    if (hardwareId.contains(C0C_PORT_DEVICE_ID, Qt::CaseInsensitive)) {
        // 检查是否有端口名称来区分虚拟端口和总线设备
        if (!portName.isEmpty()) {
            // 检查是否为标准COM端口格式（使用C0C_PORT_NAME_COMCLASS宏）
            if (portName.startsWith("COM", Qt::CaseInsensitive)) {
                return DeviceType::VirtualPort;
            } 
            // 检查是否为CNCA或CNCB类型的虚拟端口
            else if (portName.startsWith(C0C_PREF_PORT_NAME_A, Qt::CaseInsensitive) || 
                     portName.startsWith(C0C_PREF_PORT_NAME_B, Qt::CaseInsensitive)) {
                return DeviceType::VirtualPortCst;
            }
        } else {
            return DeviceType::BusDevice;
        }
    }
    
    // 进一步检查硬件ID是否匹配CNC端口类或COM端口类
    if (hardwareId.contains(C0C_PORT_HW_ID_CNCCLASS, Qt::CaseInsensitive)) {
        return DeviceType::VirtualPortCst;
    }
    
    if (hardwareId.contains(C0C_PORT_HW_ID_COMCLASS, Qt::CaseInsensitive)) {
        return DeviceType::VirtualPort;
    }
    
    return DeviceType::Unknown;
}

/**
 * @brief 验证端口名称有效性
 * @param portName 端口名称
 * @return 是否有效
 */
bool DriverManager::isValidPortName(const QString& portName)
{
    if (portName.isEmpty()) {
        qDebug() << "端口名称为空";
        return false;
    }
    
    if (portName.length() > C0C_PORT_NAME_LEN) {
        qDebug() << QString("端口名称 %1 长度超过限制 (%2)").arg(portName).arg(C0C_PORT_NAME_LEN);
        return false;
    }
    
    // 检查端口是否已被其他设备使用
    QByteArray portNameBytes = portName.toLocal8Bit();
    const char* pPortName = portNameBytes.constData();
    
    char deviceName[80];
    if (QueryDosDevice(pPortName, deviceName, sizeof(deviceName))) {
        qDebug() << QString("端口名称 %1 已被其他设备使用: %2")
                        .arg(portName, QString::fromLocal8Bit(deviceName));
        return false;
    }
    
    // 检查COM端口数据库中的使用状态
    if (s_comDbInitialized) {
        bool inUse = false;
        if (ComDbGetInUse(portName.toLocal8Bit().constData(), inUse) && inUse) {
            qDebug() << QString("端口名称 %1 在COM端口数据库中标记为使用中").arg(portName);
            return false;
        }
    }
    
    return true;
}

/**
 * @brief 显示消息框
 * @param type 消息类型
 * @param message 消息内容
 * @return 用户选择结果
 */
int DriverManager::showMessage(MessageType type, const QString& message)
{
    QWidget* parent = getMainWindow();
    
    switch (type) {
    case MessageType::Information:
        return QMessageBox::information(parent, "信息", message, QMessageBox::Ok);
        
    case MessageType::Warning:
        return QMessageBox::warning(parent, "警告", message, QMessageBox::Ok);
        
    case MessageType::Error:
        return QMessageBox::critical(parent, "错误", message, QMessageBox::Ok);
        
    case MessageType::Question:
        return QMessageBox::question(parent, "确认", message, 
                                     QMessageBox::Yes | QMessageBox::No);
        
    default:
        return QMessageBox::information(parent, "消息", message, QMessageBox::Ok);
    }
}

/**
 * @brief 获取主窗口指针
 * @return 主窗口指针，如果没有找到则返回nullptr
 */
QWidget* DriverManager::getMainWindow()
{
    QWidgetList widgets = QApplication::topLevelWidgets();
    for (QWidget* widget : widgets) {
        if (widget->isVisible()) {
            return widget;
        }
    }
    return nullptr;
}

/**
 * @brief 等待没有待处理的安装事件
 * @param timeLimit 时间限制（毫秒）
 * @param repeat 是否重复等待
 * @return 是否成功等待
 */
bool DriverManager::waitForInstallEvents(int timeLimit, bool repeat)
{
    ADD_LOG(QString(">>> Begin Wait Install Event, Timeout: %1ms <<<").arg(timeLimit));
    
    const bool infinite = (timeLimit < 0);
    DWORD startTime = GetTickCount();
    int stableSuccessCount = 0;

    for (;;) {
        DWORD res = CMP_WaitNoPendingInstallEvents(0);

        if (res == WAIT_OBJECT_0) {
            if (++stableSuccessCount < 5) {
                QThread::msleep(100);
                QApplication::processEvents();
                continue;
            }
            ADD_LOG(">>> Wait Finished (SUCCESS) <<<");
            SetLastError(ERROR_SUCCESS);
            return true;
        }
        // 非成功则重置计数
        stableSuccessCount = 0;

        if (res != WAIT_TIMEOUT) {
            // 与 com0com 一致：非超时的错误视为失败
            ADD_LOG(">>> CMP_WaitNoPendingInstallEvents Error (OTHER_ERROR) <<<");
            return false;
        }

        // 超时窗口处理
        DWORD elapsed = GetTickCount() - startTime;
        if (!infinite && elapsed >= DWORD(timeLimit * 1000)) {
            ADD_LOG(">>> Event Wait Timeout (TIMEOUT) <<<");

            if (repeat) {
                // 与 com0com 的“重复等待”对齐：重置计时继续等待（无交互）
                startTime = GetTickCount();
                continue;
            }

            // com0com 语义：超时仍返回成功，但设置 ERROR_TIMEOUT
            SetLastError(ERROR_TIMEOUT);
            return true;
        }

        // 轮询节奏（com0com 是 1000ms，这里保留 UI 响应更细粒度）
        QThread::msleep(100);
        QApplication::processEvents();
    }
}

/**
 * @brief 获取设备列表
 * @return 设备信息列表
 */
const QList<DeviceInfo>& DriverManager::getDeviceList() const
{
    return m_deviceInfoList;
}

/**
 * @brief 获取设备数量
 * @return 设备数量
 */
int DriverManager::getDeviceCount() const
{
    return m_deviceCount;
}

/**
 * @brief 检查是否已初始化
 * @return 是否已初始化
 */
bool DriverManager::isInitialized() const
{
    return m_isInitialized;
}

/**
 * @brief 定时器超时处理
 */
void DriverManager::onTimerTimeout()
{
    // 定期检查设备状态变化
    refreshDeviceList();
}
